﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Djs.HW.Util.MsCommPort.Forms
{
	public partial class ShowGraph : Form
	{
		public ShowGraph()
		{
			InitializeComponent();
			InitIntern();
		}
		#region Inicializace
		private void InitIntern()
		{
			_ComPortInit();
			_IrReceiverInit();
			_GraphInit();
			this.Shown += new EventHandler(ShowGraph_Shown);
		}
		void ShowGraph_Shown(object sender, EventArgs e)
		{
			if (ParamIsRun)
				this._IrReceiver.StartReceive(this._PortName);
		}
		#endregion
		#region Argumenty
		public string[] Arguments;
		private bool ParamIsRun
		{
			get
			{
				if (this.Arguments == null) return false;
				foreach (string arg in this.Arguments)
				{
					if (arg.ToLower().Contains("run"))
						return true;
				}
				return false;
			}
		}
		private string ParamCom
		{
			get
			{
				if (this.Arguments == null) return null;
				foreach (string arg in this.Arguments)
				{
					if (arg.ToLower().StartsWith("com"))
						return arg;
				}
				return null;
			}
		}
		#endregion
		#region Obsluha Toolbaru
		private void _ToolPlay_Click(object sender, EventArgs e)
		{
			this._IrReceiver.StartReceive(this._PortName);
		}

		private void _ToolPause_Click(object sender, EventArgs e)
		{
			this._IrReceiver.StopReceive();
		}

		private void _ToolClear_Click(object sender, EventArgs e)
		{
			this._GraphClear();
		}

		private void _ToolExit_Click(object sender, EventArgs e)
		{
			this._IrReceiver.StopReceive();
			this._IrReceiver.Dispose();
			this.Close();
		}
		#endregion
		#region COM PORT
		private void _ComPortInit()
		{
			this._ToolPort.DropDownItems.Clear();
			List<string> ports = new List<string>(System.IO.Ports.SerialPort.GetPortNames());
			ports.Sort();
			foreach (string port in ports)
			{
				System.Windows.Forms.ToolStripMenuItem comx = new System.Windows.Forms.ToolStripMenuItem();

				comx.Name = "_Tool" + port;
				comx.Text = port;
				comx.Tag = port;
				comx.Click += new EventHandler(this._ToolComX_Click);
				this._ToolPort.DropDownItems.Add(comx);
			}
			string presetPort = this.ParamCom;
			if (presetPort != null)
				_SetPortName(presetPort.Trim().ToUpper());
			else
				_SetPortName(ports[0]);
		}
		private void _ToolComX_Click(object sender, EventArgs e)
		{
			string port = (sender as ToolStripItem).Tag as string;
			this._SetPortName(port);
		}
		private void _SetPortName(string portName)
		{
			this._PortName = portName;
			this._ToolPort.Text = portName;
			this._StatusCom.Text = portName;
		}
		private string _PortName;
		#endregion
		#region IR receiver: Init, Start, Stop
		private void _IrReceiverInit()
		{
			this._IrReceiver = new IrReceiver(20m);
			this._IrReceiver.IrReceivedPacket += new IrReceiver.IrReceivedPacketEventHandler(_IrReceivePacket);
		}
		void _IrReceivePacket(object sender, IrReceiver.PacketReceivedEventArgs e)
		{
			this._AddPacketToGraph(e.ReceivedPacket.Clone());
		}
		private IrReceiver _IrReceiver;
		#endregion
		#region Graf
		private void _GraphInit()
		{
			this._Graphs = new List<LogAnalyzerGraph>();
			_InnerMargin = _List.Width - _Inner.Width;
			_List.SizeChanged += new EventHandler(_List_SizeChanged);
			_GraphClear();
			_GraphBackColors = new Color[] {
				Color.DarkBlue,
				Color.DarkCyan,
				Color.DarkGoldenrod,
				Color.DarkGreen,
				Color.DarkKhaki,
				Color.DarkOliveGreen,
				Color.DarkOrchid,
				Color.DarkRed,
				Color.DarkSeaGreen,
				Color.DarkSlateBlue,
				Color.DarkSlateGray };
			_GraphBackColorIndex = 0;
		}
		private int _InnerMargin;
		void _List_SizeChanged(object sender, EventArgs e)
		{
			int w = _List.Width - _InnerMargin;
			_Inner.Width = w;
			foreach (Control ctrl in _Inner.Controls)
				ctrl.Width = w;

			this._GraphSetMeasures();
		}
		private void _GraphClear()
		{
			_Inner.Controls.Clear();
			_Graphs.Clear();
			_Inner.Height = 0;
			_Inner.Refresh();
		}
		private void _AddPacketToGraph(IrReceiver.ReceivedPacket packet)
		{
			if (_Inner.InvokeRequired)
				// Invokace threadu ownera:
				_Inner.BeginInvoke(new Action<IrReceiver.ReceivedPacket>(_AddPacketToGraph), packet);
			else
			{
				// Přidání grafu pro paket:
				LogAnalyzerGraph graph = new LogAnalyzerGraph();
				_GraphBackColorIndex++;
				if (_GraphBackColorIndex >= (_GraphBackColors.Length - 1))
					_GraphBackColorIndex = 0;
				graph.BackColor = _GraphBackColors[_GraphBackColorIndex];

				_Graphs.Add(graph);

				_Inner.Controls.Add(graph);

				int y = _Inner.Height + 2;
				int h = 30;
				graph.Bounds = new Rectangle(0, y, _Inner.Width, h);
				_Inner.Height = y + h;
				graph.Packet = packet;

				this._GraphSetMeasures();

				if (_Inner.Height > _List.ClientSize.Height)
					_List.ScrollControlIntoView(graph);
			}
		}
		private Color[] _GraphBackColors;
		private int _GraphBackColorIndex;
		private void _GraphSetMeasures()
		{
			decimal timeMax = 0M;
			foreach (LogAnalyzerGraph graph in _Graphs)
				graph.DetectTimeMax(ref timeMax);

			foreach (LogAnalyzerGraph graph in _Graphs)
				graph.SetTimeMax(timeMax);

		}
		private List<LogAnalyzerGraph> _Graphs;

		#endregion
	}
}
